﻿using JNPF.Basics.Models;
using JNPF.Utils;
using System;
using System.Collections.Generic;
using System.Net.WebSockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace JNPF.Basics.Logic
{
    /// <summary>
    /// 系统消息
    /// 版 本：V3.0.0
    /// 版 权：引迈信息技术有限公司（https://www.jnpfsoft.com）
    /// 作 者：JNPF开发平台组
    /// 日 期：2017-12-27 
    /// </summary>
    public class MessageBll
    {
        private MessageIService service = new MessageService();
        private static List<WebSocket> _webSocket;
        private UserOnlineBll userOnlineBll = new UserOnlineBll();

        public MessageBll() { }

        public MessageBll(List<WebSocket> socket)
        {
            _webSocket = socket;
        }


        /// <summary>
        /// 列表（通知公告）
        /// </summary>
        /// <param name="requestParam">请求参数</param>
        /// <returns></returns>
        public async Task<PageResult<MessageEntity>> GetNoticeList(PageInput requestParam)
        {
            try
            {
                return await service.GetNoticeList(requestParam);
            }
            catch (Exception ex)
            {
                throw ExceptionEx.Throw(ex);
            }
        }

        /// <summary>
        /// 列表（通知公告）
        /// </summary>
        /// <param name="requestParam"></param>
        /// <returns></returns>
        public async Task<PageResult<MessageEntity>> GetNoticeList()
        {
            try
            {
                var requestParam = new PageInput();
                return await service.GetNoticeList(requestParam);
            }
            catch (Exception ex)
            {
                throw ExceptionEx.Throw(ex);
            }
        }
        /// <summary>
        /// 列表(通知公告/系统消息/私信消息)
        /// </summary>
        /// <param name="requestParam">请求参数</param>
        /// <param name="type">类别</param>
        /// <returns></returns>
        public async Task<PageResult<MessageEntity>> GetMessageList(PageInput requestParam, string type = null)
        {
            try
            {
                var userId = UserProvider.Instance.Get().UserId;
                return await service.GetMessageList(requestParam, userId, type);
            }
            catch (Exception ex)
            {
                throw ExceptionEx.Throw(ex);
            }
        }
        /// <summary>
        /// 信息
        /// </summary>
        /// <param name="id">主键值</param>
        /// <returns></returns>
        public async Task<MessageEntity> GetInfo(string id)
        {
            try
            {
                var entity = await service.GetInfo(id);
                if (entity != null)
                {
                    entity.BodyText = WebHelper.HtmlDecode(entity.BodyText);
                }
                return entity;
            }
            catch (Exception ex)
            {
                throw ExceptionEx.Throw(ex);
            }
        }
        /// <summary>
        /// 默认消息
        /// </summary>
        /// <param name="type">类别:1-通知公告/2-系统消息</param>
        /// <returns></returns>
        public async Task<MessageEntity> GetInfoDefault(int type)
        {
            try
            {
                var entity = await service.GetInfoDefault(type);
                if (entity != null)
                    return entity;
                else
                    return default(MessageEntity);
            }
            catch (Exception ex)
            {
                throw ExceptionEx.Throw(ex);
            }
        }
        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="entity">实体对象</param>
        public async Task Delete(MessageEntity entity)
        {
            try
            {
                await service.Delete(entity);
            }
            catch (Exception ex)
            {
                throw ExceptionEx.Throw(ex);
            }
        }
        /// <summary>
        /// 创建
        /// </summary>
        /// <param name="entity">实体对象</param>
        public async Task Create(MessageEntity entity)
        {
            try
            {
                entity.Id = CommonHelper.Guid;
                entity.BodyText = WebHelper.HtmlEncode(entity.BodyText);
                entity.Type = 1;
                entity.EnabledMark = 0;
                entity.CreatorTime = DateTime.Now;
                entity.CreatorUserId = UserProvider.Instance.Get().UserId;
                await service.Create(entity);
            }
            catch (Exception ex)
            {
                throw ExceptionEx.Throw(ex);
            }
        }
        /// <summary>
        /// 更新
        /// </summary>
        /// <param name="id">主键值</param>
        /// <param name="entity">实体对象</param>
        public async Task Update(string id, MessageEntity entity)
        {
            try
            {
                entity.Id = id;
                entity.BodyText = WebHelper.HtmlEncode(entity.BodyText);
                entity.LastModifyTime = DateTime.Now;
                entity.LastModifyUserId = UserProvider.Instance.Get().UserId;
                await service.Update(entity);
            }
            catch (Exception ex)
            {
                throw ExceptionEx.Throw(ex);
            }
        }
        /// <summary>
        /// 已读消息
        /// </summary>
        /// <param name="messageId">消息主键</param>
        public async Task MessageRead(string messageId)
        {
            try
            {
                var userId = UserProvider.Instance.Get().UserId;
                await service.MessageRead(userId, messageId);
            }
            catch (Exception ex)
            {
                throw ExceptionEx.Throw(ex);
            }
        }
        /// <summary>
        /// 消息已读
        /// </summary>
        public async Task MessageRead()
        {
            try
            {
                var userId = UserProvider.Instance.Get().UserId;
                await service.MessageRead(userId);
            }
            catch (Exception ex)
            {
                throw ExceptionEx.Throw(ex);
            }
        }
        /// <summary>
        /// 删除记录
        /// </summary>
        /// <param name="messageIds">消息Id</param>
        public async Task DeleteRecord(List<string> messageIds)
        {
            try
            {
                var userId = UserProvider.Instance.Get().UserId;
                await service.DeleteRecord(userId, messageIds);
            }
            catch (Exception ex)
            {
                throw ExceptionEx.Throw(ex);
            }
        }
        /// <summary>
        /// 获取未读数量（含 通知公告、系统消息）
        /// </summary>
        /// <param name="userId">用户主键</param>
        /// <returns></returns>
        public async Task<int> GetUnreadCount(string userId)
        {
            try
            {
                return await service.GetUnreadCount(userId);
            }
            catch (Exception ex)
            {
                throw ExceptionEx.Throw(ex);
            }
        }
        /// <summary>
        /// 获取公告未读数量
        /// </summary>
        /// <param name="userId">用户主键</param>
        /// <returns></returns>
        public async Task<int> GetUnreadNoticeCount(string userId)
        {
            try
            {
                return await service.GetUnreadNoticeCount(userId);
            }
            catch (Exception ex)
            {
                throw ExceptionEx.Throw(ex);
            }
        }
        /// <summary>
        /// 获取消息未读数量
        /// </summary>
        /// <param name="userId">用户主键</param>
        /// <returns></returns>
        public async Task<int> GetUnreadMessageCount(string userId)
        {
            try
            {
                return await service.GetUnreadMessageCount(userId);
            }
            catch (Exception ex)
            {
                throw ExceptionEx.Throw(ex);
            }
        }
        /// <summary>
        /// 发送公告
        /// </summary>
        /// <param name="toUserIds">发送用户</param>
        /// <param name="entity">消息信息</param>
        public async Task SentNotice(List<string> toUserIds, MessageEntity entity)
        {
            try
            {
                var userInfo = UserProvider.Instance.Get();
                entity.EnabledMark = 1;
                entity.LastModifyTime = DateTime.Now;
                entity.LastModifyUserId = userInfo.UserId;
                await service.Update(entity);
                List<MessageReceiveEntity> receiveEntityList = new List<MessageReceiveEntity>();
                foreach (var item in toUserIds)
                {
                    MessageReceiveEntity messageReceiveEntity = new MessageReceiveEntity();
                    messageReceiveEntity.Id = CommonHelper.Guid;
                    messageReceiveEntity.MessageId = entity.Id;
                    messageReceiveEntity.UserId = item;
                    messageReceiveEntity.IsRead = 0;
                    receiveEntityList.Add(messageReceiveEntity);

                }
                await service.Update(entity, receiveEntityList);
                //消息推送 - PC端
                foreach (var item in _webSocket)
                {
                    SendAsync(item, new { method = "messagePush", userId = userInfo.TenantId, toUserId = toUserIds, title = entity.Title, unreadNoticeCount = 1 }.ToJson());
                }
                //消息推送 - APP
                //  GetuiAppPushHelper.Instance.SendNotice(userInfo.TenantId, toUserIds, "系统公告", entity.F_Title, "1");
            }
            catch (Exception ex)
            {
                throw ExceptionEx.Throw(ex);
            }
        }
        /// <summary>
        /// 发送消息
        /// </summary>
        /// <param name="toUserIds">发送用户</param>
        /// <param name="title">标题</param>
        /// <param name="bodyText">内容</param>
        public async Task SentMessage(List<string> toUserIds, string title, string bodyText = null)
        {
            try
            {
                var userInfo = UserProvider.Instance.Get();
                MessageEntity entity = new MessageEntity();
                entity.Title = title;
                entity.BodyText = bodyText;
                entity.Id = CommonHelper.Guid;
                entity.Type = 2;
                entity.CreatorTime = DateTime.Now;
                entity.CreatorUserId = userInfo.UserId;
                entity.LastModifyTime = entity.CreatorTime;
                entity.LastModifyUserId = entity.CreatorUserId;
                List<MessageReceiveEntity> receiveEntityList = new List<MessageReceiveEntity>();
                foreach (var item in toUserIds)
                {
                    MessageReceiveEntity messageReceiveEntity = new MessageReceiveEntity();
                    messageReceiveEntity.Id = CommonHelper.Guid;
                    messageReceiveEntity.MessageId = entity.Id;
                    messageReceiveEntity.UserId = item;
                    messageReceiveEntity.IsRead = 0;
                    receiveEntityList.Add(messageReceiveEntity);
                }
                await service.Create(entity, receiveEntityList);
                //消息推送 - PC端
                foreach (var item in _webSocket)
                {
                    SendAsync(item, new { method = "messagePush", userId = userInfo.TenantId, toUserId = toUserIds, title = entity.Title, unreadNoticeCount = 1 }.ToJson());
                }
                //消息推送 - APP
                // GetuiAppPushHelper.Instance.SendNotice(userInfo.TenantId, toUserIds, "系统消息", entity.F_Title, "2");
            }
            catch (Exception ex)
            {
                throw ExceptionEx.Throw(ex);
            }
        }

        private static void SendAsync(WebSocket socket, string message, CancellationToken ct = default(CancellationToken))
        {
            try
            {
                var buffer = Encoding.UTF8.GetBytes(message);
                var segment = new ArraySegment<byte>(buffer);
                socket.SendAsync(segment, WebSocketMessageType.Text, true, ct);
            }
            catch (Exception ex)
            {
                LogFactory.GetLogger().Error("SendAsync - OnError");
                LogFactory.GetLogger().Error(ex);
                throw;
            }
        }
    }
}
